<template>
  <div>
    <a-card
      style="margin-top: 24px"
      :bordered="false">
      <div slot="extra">
        <a-radio-group
          button-style="solid"
          default-value="">
          <a-radio-button
            @click="handleQuery()"
            value="">
            All
          </a-radio-button>
          <a-radio-button
            @click="handleQuery(-1)"
            value="-1">
            Not Build
          </a-radio-button>
          <a-radio-button
            @click="handleQuery(0)"
            value="0">
            Building
          </a-radio-button>
          <a-radio-button
            @click="handleQuery(1)"
            value="1">
            Build Success
          </a-radio-button>
          <a-radio-button
            @click="handleQuery(2)"
            value="2">
            Build Failed
          </a-radio-button>
        </a-radio-group>
        <a-input-search
          @search="handleSearch"
          style="margin-left: 16px; width: 272px;" />
      </div>

      <div
        class="operate"
        v-permit="'project:create'">
        <a-button
          type="dashed"
          style="width: 100%"
          icon="plus"
          @click="handleAdd">
          Add New
        </a-button>
      </div>

      <a-list
        size="large"
        :pagination="pagination">
        <a-list-item
          :key="index"
          v-for="(item, index) in dataSource">
          <a-list-item-meta>
            <a-badge class="build-badge" v-if="item.buildState === -2" slot="avatar" count="NEW" title="this project has changed,need rebuild">
              <svg-icon class="avatar" v-if="item.type === 1" name="flink" size="large"></svg-icon>
              <svg-icon class="avatar" v-if="item.type === 2" name="spark" size="large"></svg-icon>
            </a-badge>
            <template v-else>
              <svg-icon class="avatar" v-if="item.type === 1" name="flink" size="large" slot="avatar"></svg-icon>
              <svg-icon class="avatar" v-if="item.type === 2" name="spark" size="large" slot="avatar"></svg-icon>
            </template>
            <a slot="title">
              {{ item.name }}
              <a-badge
                status="processing"
                title="installing"
                v-if="item.buildState === 0" />
            </a>
            <a-popover
              arrow-point-at-center
              trigger="hover"
              slot="description">
              <template slot="content">
                {{ item.url }}
              </template>
              <a-button
                style="border:unset;height:20px;background:unset;margin-left:0;padding-left:0px;">
                <ellipsis
                  :length="controller.ellipsis">
                  {{ item.description }}
                </ellipsis>
              </a-button>
            </a-popover>
          </a-list-item-meta>

          <div class="list-content-item">
            <p>
              <a-tag
                color="blue">
                {{ item.teamName }}
              </a-tag>
            </p>
          </div>

          <div class="list-content">
            <div
              class="list-content-item">
              <span>CVS</span>
              <p>
                <a-icon
                  type="github"
                  two-tone-color />
              </p>
            </div>


            <div class="list-content-item">
              <span>Branches</span>
              <p>
                <a-tag
                  color="blue">
                  {{ item.branches }}
                </a-tag>
              </p>
            </div>
            <div
              class="list-content-item"
              style="width: 180px">
              <span>Last Build</span>
              <p v-if="item.lastBuild">
                {{ item.lastBuild }}
              </p>
              <p v-else>
                --
              </p>
            </div>
            <div
              class="list-content-item"
              style="width: 150px">
              <span>Build State</span>
              <p v-if="item.buildState === -1">
                <a-tag color="#C0C0C0">NOT BUILD</a-tag>
              </p>
              <p v-if="item.buildState === -2">
                <a-tag color="#FFA500">NEED REBUILD</a-tag>
              </p>
              <p v-else-if="item.buildState === 0">
                <a-tag color="#1AB58E" class="status-processing-building">BUILDING</a-tag>
              </p>
              <p v-else-if="item.buildState === 1">
                <a-tag color="#52c41a">SUCCESSFUL</a-tag>
              </p>
              <p v-else>
                <a-tag color="#f5222d">FAILED</a-tag>
              </p>
            </div>
          </div>

          <div class="operation">

            <a-tooltip
              title="See Build log"
              v-if="item.buildState === 0">
              <a-button
                shape="circle"
                size="small"
                style="margin-left: 8px"
                @click.native="handleSeeLog(item)"
                class="control-button ctl-btn-color">
                <a-icon
                  spin
                  type="sync"
                  style="color:#4a9ff5"/>
              </a-button>
            </a-tooltip>

            <a-tooltip
              title="Build Project"
              v-if="item.buildState !== 0"
              v-permit="'project:build'">
              <a-popconfirm
                title="Are you sure build this project?"
                cancel-text="No"
                ok-text="Yes"
                @confirm="handleBuild(item)">
                <a-button
                  shape="circle"
                  size="small"
                  style="margin-left: 8px"
                  class="control-button ctl-btn-color">
                  <a-icon type="thunderbolt" />
                </a-button>
              </a-popconfirm>
            </a-tooltip>

            <a-tooltip title="Update Project">
              <a-button
                v-permit="'project:update'"
                @click.native="handleEdit(item)"
                shape="circle"
                size="small"
                style="margin-left: 8px"
                class="control-button ctl-btn-color">
                <a-icon type="edit"/>
              </a-button>
            </a-tooltip>

            <a-tooltip title="Delete Project">
              <a-popconfirm
                title="Are you sure delete this project ?"
                cancel-text="No"
                ok-text="Yes"
                @confirm="handleDelete(item)">
                <a-button
                  type="danger"
                  shape="circle"
                  size="small"
                  style="margin-left: 8px"
                  class="control-button">
                  <a-icon type="delete"/>
                </a-button>
              </a-popconfirm>
            </a-tooltip>

          </div>

        </a-list-item>
      </a-list>
    </a-card>

    <a-modal
      v-model="controller.visible"
      width="65%"
      :body-style="controller.modalStyle"
      :destroy-on-close="controller.modalDestroyOnClose"
      :footer="null"
      @cancel="handleClose">
      <template slot="title">
        <svg-icon name="code" />&nbsp;
        {{ controller.consoleName }}
      </template>
      <div
        id="terminal"
        ref="terminal"
        class="terminal" />
    </a-modal>
  </div>
</template>
<script>
import { build, buildlog, list,remove,closebuild } from '@api/project'
import Ellipsis from '@comp/Ellipsis'
import {mapActions} from 'vuex'
import { Terminal } from 'xterm'
import 'xterm/css/xterm.css'

import SvgIcon from '@/components/SvgIcon'
import {baseUrl} from '@/api/baseUrl'
import storage from '@/utils/storage'

export default {
  components: { Ellipsis, SvgIcon },
  data () {
    return {
      loading: false,
      advanced: false,
      dataSource: [],
      queryParams: {},
      sortedInfo: null,
      stompClient: null,
      terminal: null,
      projectId: null,
      socketId: null,
      storageKey: 'BUILD_SOCKET_ID',
      controller: {
        ellipsis: 100,
        modalStyle: {
          height: '600px',
          padding: '5px'
        },
        visible: false,
        modalDestroyOnClose: true,
        consoleName: null
      },
      pagination: {
        pageSizeOptions: ['10', '20', '30', '40', '100'],
        defaultCurrent: 1,
        defaultPageSize: 10,
        showQuickJumper: true,
        showSizeChanger: true,
        onChange:(page,pageSize)=>{
          this.queryParams.pageNum = page
          this.handleFetch(this.queryParams, false)
        },
        onShowSizeChange:(current,size)=>{
          this.queryParams.pageNum = 1
          this.queryParams.pageSize = size
          this.handleFetch(this.queryParams, false)
        },
        showTotal: (total, range) => `display ${range[0]} ~ ${range[1]} record，total ${total} `
      }
    }
  },

  mounted () {
    this.handleFetch(this.queryParams, true)
    const timer = window.setInterval(() => this.handleFetch(this.queryParams, false), 2000)
    this.$once('hook:beforeDestroy', () => {
      clearInterval(timer)
    })
  },

  methods: {
    ...mapActions(['SetProjectId']),

    handleSearch (value) {
      this.paginationInfo = null
      this.queryParams.name = value
      this.handleFetch({
        ...this.queryParams
      }, true)
    },

    handleBuild (record) {
      this.$swal.fire({
        icon: 'success',
        title: 'The current project is building',
        showConfirmButton: false,
        timer: 2000
      }).then((r)=> {
        this.socketId = this.uuid()
        storage.set(this.storageKey,this.socketId)
        build({
          id: record.id,
          socketId: this.socketId
        })
      })
    },

    handleAdd () {
      this.$router.push({ 'path': '/flink/project/add' })
    },

    handleEdit(item) {
      this.SetProjectId(item.id)
      this.$router.push({'path': '/flink/project/edit'})
    },

    handleDelete(item) {
      remove({
        id: item.id
      }).then((resp) => {
        if ( resp.data ) {
          this.$swal.fire({
            icon: 'success',
            title: 'delete successful',
            showConfirmButton: false,
            timer: 2000
          }).then((result) => {
            this.handleFetch(this.queryParams, true)
          })
        } else {
          this.$swal.fire(
            'Failed',
            'Please check if any application belongs to this project',
            'error'
          )
        }
      })
    },

    handleSeeLog (project) {
      this.controller.consoleName = project.name + ' build log'
      this.controller.visible = true
      this.$nextTick(function () {
        this.handleOpenWS(project)
      })
    },

    handleOpenWS (project) {
      this.projectId = project.id
      const rows = parseInt(this.controller.modalStyle.height.replace('px', '')) / 16
      const cols = (document.querySelector('.terminal').offsetWidth - 10) / 8
      this.terminal = new Terminal({
        cursorBlink: true,
        rendererType: 'canvas',
        termName: 'xterm',
        useStyle: true,
        screenKeys: true,
        convertEol: true,
        scrollback: 1000,
        tabstopwidth: 4,
        disableStdin: true,
        rows: parseInt(rows), // 行数
        cols: parseInt(cols),
        fontSize: 14,
        cursorStyle: 'underline', // 光标样式
        theme: {
          foreground: '#AAAAAA', // 字体
          background: '#131D32', // 背景色
          lineHeight: 16
        }
      })
      const container = document.getElementById('terminal')
      this.terminal.open(container, true)

      const url = baseUrl().concat('/websocket/' + this.handleGetSocketId())

      const socket = this.getSocket(url)

      socket.onopen = () => {
        buildlog({id:project.id})
      }

      socket.onmessage = (event) => {
        this.terminal.writeln(event.data)
      }

      socket.onclose = () => {
        this.socketId = null
        storage.rm(this.storageKey)
      }

    },

    handleGetSocketId() {
      if (this.socketId == null) {
        return storage.get(this.storageKey) || null
      }
      return this.socketId
    },

    handleClose () {
      closebuild({ id: this.projectId })
      this.stompClient.disconnect()
      this.controller.visible = false
      this.terminal.clear()
      this.terminal.clearSelection()
      this.terminal = null
    },

    handleQuery (state) {
      this.queryParams.buildState = state
      this.handleFetch({
        ...this.queryParams
      }, true)
    },

    handleFetch (params, loading) {
      if (loading) {
        this.loading = true
      }
      if (this.paginationInfo) {
        // 如果分页信息不为空，则设置表格当前第几页，每页条数，并设置查询分页参数
        this.$refs.TableInfo.pagination.current = this.paginationInfo.current
        this.$refs.TableInfo.pagination.pageSize = this.paginationInfo.pageSize
        params.pageSize = this.paginationInfo.pageSize
        params.pageNum = this.paginationInfo.current
      } else {
        // 如果分页信息为空，则设置为默认值
        // params.pageSize = this.pagination.defaultPageSize
        // params.pageNum = this.pagination.current
      }
      list({
        ...params
      }).then((resp) => {
        const pagination = { ...this.pagination }
        pagination.total = parseInt(resp.data.total)
        this.dataSource = resp.data.records
        this.pagination = pagination
        this.loading = false
      })
    }
  }
}
</script>

<style lang="less" scoped>
.ant-avatar-lg {
  width: 48px;
  height: 48px;
  line-height: 48px;
}

.list-content-item {
  display: inline-block;
  vertical-align: middle;
  font-size: 14px;
  margin-left: 40px;

  span {
    line-height: 20px;
  }

  p {
    margin-top: 4px;
    margin-bottom: 0;
    line-height: 22px;
  }
}

.gutter-box {
  padding: 10px 20px;
  color: rgba(0, 0, 0, 0.65);
  font-size: 14px;
  font-variant: tabular-nums;
  line-height: 1.5;
  list-style: none;
  -webkit-font-feature-settings: 'tnum';
  font-feature-settings: 'tnum';
  position: relative;
  border-radius: 2px;
  transition: all 0.3s;
}

.operation {
  width: 120px;
}

.ant-tag {
  border-radius: 0;
  font-weight: 700;
  font-size: 12px;
  text-align: center;
  padding: 0 4px;
  margin-right: 0px;
  cursor: default;
}

.avatar {
  border-radius: 50%;
  background-color: #ebebeb;
  border: 6px solid #ebebeb;
}

.status-processing-building {
  animation: building-color 800ms ease-out infinite alternate;
}

@keyframes building-color {
  0% {
    border-color: #1AB58E;
    box-shadow: 0 0 1px #1AB58E, inset 0 0 2px #1AB58E;
  }
  100% {
    border-color: #1AB58E;
    box-shadow: 0 0 10px #1AB58E, inset 0 0 5px #1AB58E;
  }
}

.build-badge {
  font-size : 12px;
  -webkit-transform : scale(0.84,0.84) ;
  *font-size:10px;
}
</style>
